package org.seamon.management.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.seamon.management.mapper.SmsTaskMapper;
import org.seamon.management.pojo.dto.SmsSendDto;
import org.seamon.management.pojo.dto.SmsTaskListDto;
import org.seamon.management.pojo.entity.SmsTask;
import org.seamon.management.pojo.entity.User;
import org.seamon.management.pojo.vo.SmsTaskListVo;
import org.seamon.management.service.SmsTaskService;
import org.seamon.management.service.UserService;
import org.seamon.management.sms.SmsProducer;
import org.seamon.management.util.enums.ErrorCodeEnum;
import org.seamon.management.util.enums.SmsStatusEnum;
import org.seamon.management.util.exception.BusinessException;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Simon
 * @description 针对表【sms_task(短信任务队列表)】的数据库操作Service实现
 * @createDate 2025-07-11 00:32:35
 */
@Slf4j
@Service
public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper, SmsTask>
        implements SmsTaskService {

    @Resource
    private UserService userService;
    @Resource
    private SmsProducer smsProducer;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void send(SmsSendDto dto) {
        // 获取手机号
        List<User> users = userService.listByIds(dto.getUserIds());
        Map<Long, String> idPhoneMap = users.stream()
                .collect(Collectors.toMap(User::getId, User::getPhone));

        // 校验是否都存在
        Set<Long> foundIds = idPhoneMap.keySet();
        Set<Long> requestIds = new HashSet<>(dto.getUserIds());
        if (!foundIds.containsAll(requestIds)) {
            requestIds.removeAll(foundIds);
            log.error("用户不存在：{}", requestIds);
            throw new BusinessException(ErrorCodeEnum.USER_NOT_EXIST);
        }

        // 写入任务表
        List<SmsTask> smsTasks = new ArrayList<>();
        for (Map.Entry<Long, String> entry : idPhoneMap.entrySet()) {
            SmsTask smsTask = new SmsTask();
            smsTask.setUserId(entry.getKey());
            smsTask.setPhone(entry.getValue());
            smsTask.setContent(dto.getContent());
            smsTask.setStatus(SmsStatusEnum.TASK_WAITING.getCode());
            smsTask.setPriority(dto.getPriority());

            smsTasks.add(smsTask);
        }
        this.saveBatch(smsTasks);

        // 发送到 RabbitMQ
        smsProducer.send(smsTasks);
    }

    @Override
    public Page<SmsTaskListVo> list(SmsTaskListDto dto) {
        Page<SmsTask> page = new Page<>(dto.getCurrent(), dto.getSize());
        LambdaQueryWrapper<SmsTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(dto.getStatus() != null, SmsTask::getStatus, dto.getStatus())
                .le(dto.getEndTime() != null, SmsTask::getCreateTime, dto.getEndTime())
                .ge(dto.getStartTime() != null, SmsTask::getCreateTime, dto.getStartTime())
                .orderByDesc(SmsTask::getCreateTime);
        Page<SmsTask> taskPage = this.page(page, queryWrapper);
        List<SmsTaskListVo> voList = taskPage.getRecords().stream()
                .map(task -> {
                    SmsTaskListVo taskListVo = new SmsTaskListVo();
                    BeanUtils.copyProperties(task, taskListVo);
                    return taskListVo;
                })
                .collect(Collectors.toList());
        Page<SmsTaskListVo> res = new Page<>();
        res.setCurrent(taskPage.getCurrent());
        res.setSize(taskPage.getSize());
        res.setTotal(taskPage.getTotal());
        res.setRecords(voList);

        return res;
    }

    @Override
    public void retry(Long taskId) {
        SmsTask smsTask = this.getById(taskId);
        if (smsTask == null) {
            throw new BusinessException(ErrorCodeEnum.TASK_NOT_EXIST);
        }
        if (smsTask.getRetryCount() <= 0) {
            throw new BusinessException(ErrorCodeEnum.TASK_RETRY_COUNT_EXCEED);
        }
        smsTask.setStatus(SmsStatusEnum.TASK_PROCESSING.getCode());
        this.updateById(smsTask);
        List<SmsTask> smsTasks = new ArrayList<>();
        smsTasks.add(smsTask);
        smsProducer.send(smsTasks);
    }
}




